#include "..\CommLib\CommStructs.h"
#include <maya/MNodeMessage.h>
#include <maya/MIntArray.h>

class VSyncViewer {

	static void OnChangeSelection(void* clientData);
	
	static MIntArray g_RegisteredCallbacks;
	/*static MCallbackId g_ViewportRemoveObjectListenerCallback;*/
	static MCallbackId g_ViewportSelectionListenerCallback;
	static MCallbackId g_ViewportAddSceneNodeCallback;
	static MCallbackId g_ViewportAddDGNodeCallback;
	static long g_SyncTimer;
	static const long g_SyncThrottle = 50;

	struct tSyncReport {

		bool IsGeometry;
		bool IsParameters;
		bool IsInstancing;
		bool IsDeformation;
	};

	static bool IsObjectSynchronized(MObject& targetObject, tSyncReport* pReport);
	static bool CheckMatch(MObject& targetObject, QuerysStructs::tGeometryHeader* pHeader);
	static bool CheckMatch(MObject& targetObject, QuerysStructs::tGeometryPartHeader* pHeader, uint partIndex);
	static bool CheckMatch(MObject& targetObject, QuerysStructs::tChannelHeader* pHeader, uint partIndex);
	static bool CheckMatch(MObject& targetObject, QuerysStructs::tInstancingHeader* pHeader);
	static bool CheckMatch(MObject& targetObject, QuerysStructs::tInstanceChildHeader* pHeader, uint childIndex);
	static bool CheckMatch(MObject& targetObject, QuerysStructs::tDeformationHeader* pHeader);

public:

	static bool IsObjectOnServer(MObject& targetObject);

	static bool InitSelectedAttributes(MObject& target);
	
	static void AddNodeCallback(MObject &newObject, void* clientData);
	static void AddMaterialAssignmentCallback(MObject material);
	static void AddSamplerCallback(MObject material);
	static void AddLightCallback(MObject light);
	static void AddMeshCallback(MObject mesh);
	static void AddUVCallback(MObject mesh);
	static void AddTransformCallback(MObject transform);
	static void InitPluginSelection();
	static bool InitalizeObjectTypeCallbacks(MFn::Type type, MNodeMessage::MAttr2PlugFunction callback);
	static bool InitalizeCallbacks();
	static void ReleaseCallbacks();
	static void ReleaseRegisteredCallbacks();

	static void HandleInstanceSampler(MObject& instanceSampler, bool remove);
	/*static void HandleStandardSampler(MObject& sampler, bool remove);*/

	static void HandleMeshAttribute(MString& attributeName, MPlug& attributePlug);

	static bool SynchronizeSelection(MObjectArray& objects);
	static bool EntireScene();
	
	class CallbackWrappers {
	public:

		/*static void SceneExited
		static void SceneSaved
		static void SceneOpened*/
		//static void SceneRemoveObject(MObject& object, void* pClientData);
		static void RemoveObjectCallbacks(MObject& object);

		static void OnChangeLight(MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* pClientData);
		static void OnChangeSampler(MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* pClientData);
		static void OnChangeTransform( MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* pClientData);
		static void OnChangeMesh( MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* pClientData);
		static void OnChangeUV( MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* pClientData);
		//static void OnChangeMeshMaterial( MNodeMessage::AttributeMessage msg, MPlug& plug, MPlug& otherPlug, void* pClientData);
	};
};